package com.asset.dispoal.file.agreementCaseData.service.commom;


import com.asset.dispoal.business.bsAgreement.domain.db.entity.Agreement;
import com.asset.dispoal.business.bsAgreement.domain.db.entity.AgreementCase;
import com.asset.dispoal.business.bsAgreement.domain.db.entity.AgreementExpand;
import com.asset.dispoal.business.bsAgreement.domain.db.entity.AgreementStateRecord;
import com.asset.dispoal.business.bsAgreement.domain.db.mapper.AgreementMapper;
import com.asset.dispoal.business.bsBorrowDetail.domain.db.entity.BorrowDetail;
import com.asset.dispoal.business.bsBorrowDetail.domain.db.mapper.BsBorrowDetailMapper;
import com.asset.dispoal.business.bsBorrower.domain.db.entity.Borrower;
import com.asset.dispoal.business.bsBorrower.domain.db.mapper.BorrowerMapper;
import com.asset.dispoal.business.bsCase.domain.db.entity.BsCase;
import com.asset.dispoal.business.bsCase.domain.db.entity.CaseAgreement;
import com.asset.dispoal.business.bsCase.domain.db.entity.CaseStateRecord;
import com.asset.dispoal.business.bsCase.domain.db.mapper.BsCaseMapper;
import com.asset.dispoal.commom.menus.AgreementCaseSateMenu;
import com.asset.dispoal.file.agreementCaseData.domain.dto.BsDataDetailExportTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tech.mhuang.pacebox.core.date.DateTimeUtil;
import tech.mhuang.pacebox.core.ddd.BaseCommand;
import tech.mhuang.pacebox.core.id.BaseIdeable;
import tech.mhuang.pacebox.core.util.CollectionUtil;
import tech.mhuang.pacebox.springboot.core.local.GlobalHeaderThreadLocal;
import tech.mhuang.pacebox.springboot.protocol.Result;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author qr
 * @date 2021/11/24$
 */
@Component
@Slf4j
public class FileExcelDataSaveCommand implements BaseCommand<Map<String, Object>, Result> {

    @Autowired
    private BaseIdeable<String> idWorker;

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result execute(Map<String, Object> map) {
        //包含不存在身份证导入到案件、存在身份证的案件进行修改添加映射等
        // 逻辑相关先根据导入的身份证把对应的人都查询出来、若存在则对应案件是修改、不存在则是新增，
        // 1:存在合同号 不存在身份证 新增一个合同、案件
        // 2：存在身份证、不存在合同号 新增一个合同、修改对应的案件
        // 3：存在合同号 存在身份证 修改当前合同并且修改对应的案件
        // 4：都不存在则直接新增案件
        // 期间需要修改案件的需根据历史案件的合同信息查询出来、根据新的合同进行累加保存
        List<BsDataDetailExportTemplate> bsDataDetailExportTemplateList = (List<BsDataDetailExportTemplate>) map.get("dataList");
        String assetInstBatchId = (String) map.get("assetInstBatchId");

        if (CollectionUtil.isEmpty(bsDataDetailExportTemplateList)) {
            return Result.faild("导入数据为空");
        }
        SqlSession sqlSession = this.sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        AgreementMapper agreementMapper = this.sqlSessionTemplate.getMapper(AgreementMapper.class);
        BsBorrowDetailMapper bsBorrowDetailMapper = this.sqlSessionTemplate.getMapper(BsBorrowDetailMapper.class);
        BorrowerMapper borrowerMapper = this.sqlSessionTemplate.getMapper(BorrowerMapper.class);
        BsCaseMapper bsCaseMapper = this.sqlSessionTemplate.getMapper(BsCaseMapper.class);
        //身份证
        List<String> idcardList = bsDataDetailExportTemplateList.stream().map(BsDataDetailExportTemplate::getBorrower_idcard).collect(Collectors.toList());

        List<Agreement> agreements = agreementMapper.queryAgreementByByIdCardAndBatchId(assetInstBatchId, idcardList);
        //当前导入人下的所有案件
        List<CaseAgreement> caseAgreements = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(agreements)) {
            caseAgreements.addAll(bsCaseMapper.queryByAgreementId(assetInstBatchId, idcardList));
        }
        List<Agreement> agreementDtoList = new ArrayList<>(bsDataDetailExportTemplateList.size());
        List<Borrower> borrowerDtoList = new ArrayList<>(bsDataDetailExportTemplateList.size());
        List<BorrowDetail> borrowDetailDtoList = new ArrayList<>(bsDataDetailExportTemplateList.size());
        List<AgreementExpand> agreementExpandDtoList = new ArrayList<>(bsDataDetailExportTemplateList.size());

        List<AgreementCase> agreementCaseDtoList = new ArrayList<>(bsDataDetailExportTemplateList.size());

        List<String> delCaseAgreementIdList = new ArrayList<>();
        List<String> delCaseIdList = new ArrayList<>();
        Map<String, Boolean> idCardMap = new HashMap<>(idcardList.size());
        //合同相关信息生成
        for (BsDataDetailExportTemplate bsDataDetailExportTemplate : bsDataDetailExportTemplateList) {
            String agreementId = idWorker.generateId();
            Boolean updated = Boolean.FALSE;
            Boolean idCardUpdated = Boolean.FALSE;
            String lastState = null;
            String currentState = null;
            Optional<Agreement> agreementOptional = agreements.stream().filter(item -> item.getContractNo().equals(bsDataDetailExportTemplate.getContract_no()) && item.getBorrowerIdcard().equals(bsDataDetailExportTemplate.getBorrower_idcard())).findFirst();
            if (agreementOptional.isPresent()) {
                currentState = agreementOptional.get().getCaseState();
                lastState = agreementOptional.get().getLastState();
                agreementId = agreementOptional.get().getId();
                updated = Boolean.TRUE;
            }
            Optional<Agreement> idCardOptional = agreements.stream().filter(item -> item.getBorrowerIdcard().equals(bsDataDetailExportTemplate.getBorrower_idcard())).findFirst();
            if (idCardOptional.isPresent()) {
                idCardUpdated = Boolean.TRUE;
            }
            idCardMap.put(bsDataDetailExportTemplate.getBorrower_idcard(), idCardUpdated);
            Agreement agreementDto = installAgreement(agreementId, bsDataDetailExportTemplate, assetInstBatchId, updated, idCardUpdated, currentState, lastState);
            Borrower borrowerDto = installBorrower(agreementId, bsDataDetailExportTemplate, updated, idCardUpdated);
            BorrowDetail borrowDetailDto = installBorrowDetail(agreementId, bsDataDetailExportTemplate, updated, idCardUpdated);
            AgreementExpand agreementExpandDto = installAgreementExpand(agreementId, bsDataDetailExportTemplate, updated, idCardUpdated);
            agreementDtoList.add(agreementDto);
            borrowerDtoList.add(borrowerDto);
            agreementExpandDtoList.add(agreementExpandDto);
            borrowDetailDtoList.add(borrowDetailDto);
        }

        //合同新增的看身份证存不存在。身份证不存在则新增案件。以及绑定关系
        //合同新增的身份证存在则只添加案件合同绑定关系、
        //合同修改的则只修改案件，不改变其他。
        //必须所有案件汇总完后才可进行处理
        //案件生成
        Map<String, List<Borrower>> borrowerDtoListByIdcard = borrowerDtoList.stream().collect(Collectors.groupingBy(Borrower::getBorrowerIdcard));
        String userId = GlobalHeaderThreadLocal.getOrException().getUserId();
        List<BsCase> caseDtoList = new ArrayList<>(idcardList.size());
        for (String key : borrowerDtoListByIdcard.keySet()) {
            List<Borrower> borrowerDtos = borrowerDtoListByIdcard.get(key);
            Boolean idCardUpdated = idCardMap.get(key);
            //当前身份证下的所有案件
            List<CaseAgreement> matchCaseAgreementList = caseAgreements.stream().filter(caseAgreement -> key.equals(caseAgreement.getBorrowerIdcard())).collect(Collectors.toList());
            //需要移除的合同
            Set<String> removeAgreementId = new HashSet<>(borrowerDtos.size());
            //需要添加的合同
            List<String> addCaseAgreement = new ArrayList<>();
            //当前身份证则判断身份证的案件的情况
            if (idCardUpdated) {
                //循环身份证下有案件的情况，如果合同存在
                for (Borrower borrower : borrowerDtos) {
                    Agreement agreementDTO = agreementDtoList.stream().filter(agreement -> borrower.getAgreementId().equals(agreement.getId())).findFirst().get();
                    Optional<CaseAgreement> caseAgreementOptional = matchCaseAgreementList.stream().filter(caseAgreement -> agreementDTO.getId().equals(caseAgreement.getAgreementId())).findFirst();
                    //如果当前身份证号的这个合同是废案则移除
                    if (AgreementCaseSateMenu.ABOLISH_CASE.getLabel().equals(agreementDTO.getCaseState())) {
                        if (caseAgreementOptional.isPresent()) {
                            delCaseAgreementIdList.add(agreementDTO.getId());
                        }
                        removeAgreementId.add(agreementDTO.getId());
                    } else {
                        if (!caseAgreementOptional.isPresent()) {
                            addCaseAgreement.add(agreementDTO.getId());
                        }
                    }
                }
                //当前人在系统中存在
                //  有添加的合同，
                //      则查看添加的合同有没有可合并的案件，如果有则合并，没有则创建新案件
                //  如果没有添加的合同
                //      检查当前人的合同在系统中是否还有可
                //
                //未移除完则找到当前的这个人在案件下的其他状态，若案件其他状态是待派送或集证则可以可以进行合并
                if (CollectionUtil.isNotEmpty(addCaseAgreement)) {
                    Optional<CaseAgreement> findCaseAgreement = matchCaseAgreementList.stream().filter(matchCaseAgreement -> "1".equals(matchCaseAgreement.getMergeImpLink()) && !removeAgreementId.contains(matchCaseAgreement.getAgreementId())).findFirst();
                    if (findCaseAgreement.isPresent()) {
                        //合并
                        CaseAgreement caseAgreement = findCaseAgreement.get();
                        for (String agreementId : addCaseAgreement) {
                            AgreementCase agreementCaseDto = new AgreementCase();
                            agreementCaseDto.setCaseId(caseAgreement.getCaseId());
                            agreementCaseDto.setAgreementId(agreementId);
                            agreementCaseDtoList.add(agreementCaseDto);
                        }
                        //查找对应案件下的合同
                        Set<String> checkedAgreementId = matchCaseAgreementList.stream().filter(matchCaseAgreement -> caseAgreement.getCaseId().equals(matchCaseAgreement.getCaseId()) && !removeAgreementId.contains(matchCaseAgreement.getAgreementId()) && !addCaseAgreement.contains(matchCaseAgreement.getAgreementId())).map(CaseAgreement::getAgreementId).collect(Collectors.toSet());
                        List<Agreement> checkAgreementList = agreements.stream().filter(agreement -> checkedAgreementId.contains(agreement.getId())).collect(Collectors.toList());
                        //改变老的案件数据
                        BigDecimal lawsuitPrincipalAmountSum = borrowDetailDtoList.stream().filter(item -> addCaseAgreement.contains(item.getAgreementId())).map(BorrowDetail::getLawsuitPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal creditPrincipalAmountSum = borrowDetailDtoList.stream().filter(item -> addCaseAgreement.contains(item.getAgreementId())).map(BorrowDetail::getCreditPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal lawsuitInterestAmountSum = borrowDetailDtoList.stream().filter(item -> addCaseAgreement.contains(item.getAgreementId())).map(BorrowDetail::getLawsuitInterestAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        lawsuitPrincipalAmountSum = lawsuitPrincipalAmountSum.add(checkAgreementList.stream().map(Agreement::getLawsuitPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add));
                        creditPrincipalAmountSum = creditPrincipalAmountSum.add(checkAgreementList.stream().map(Agreement::getCreditPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add));
                        lawsuitInterestAmountSum = lawsuitInterestAmountSum.add(checkAgreementList.stream().map(Agreement::getLawsuitInterestAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add));
                        BsCase caseDto = new BsCase();
                        caseDto.setId(caseAgreement.getCaseId());
                        caseDto.setLawsuitPrincipalAmount(lawsuitPrincipalAmountSum);
                        caseDto.setLawsuitInterestAmount(lawsuitInterestAmountSum);
                        caseDto.setCreditPrincipalAmount(creditPrincipalAmountSum);
                        caseDto.setOperateUser(userId);
                        caseDto.setOperateTime(DateTimeUtil.currentDate());
                        caseDto.setBorrowerAddress(borrowerDtos.get(0).getBorrowerAddress());
                        caseDto.setBorrowerTel(borrowerDtos.get(0).getBorrowerTel());
                        caseDto.setBorrowerNation(borrowerDtos.get(0).getBorrowerNation());
                        caseDto.setStated(2);
                        caseDtoList.add(caseDto);
                    } else {
                        String caseId = idWorker.generateId();
                        for (String agreementId : addCaseAgreement) {
                            AgreementCase agreementCaseDto = new AgreementCase();
                            agreementCaseDto.setCaseId(caseId);
                            agreementCaseDto.setAgreementId(agreementId);
                            agreementCaseDtoList.add(agreementCaseDto);
                        }
                        //新增案件数据
                        BigDecimal lawsuitPrincipalAmountSum = borrowDetailDtoList.stream().filter(item -> addCaseAgreement.contains(item.getAgreementId())).map(BorrowDetail::getLawsuitPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal creditPrincipalAmountSum = borrowDetailDtoList.stream().filter(item -> addCaseAgreement.contains(item.getAgreementId())).map(BorrowDetail::getCreditPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal lawsuitInterestAmountSum = borrowDetailDtoList.stream().filter(item -> addCaseAgreement.contains(item.getAgreementId())).map(BorrowDetail::getLawsuitInterestAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BsCase caseDto = new BsCase();
                        caseDto.setId(caseId);
                        caseDto.setBorrowerAddress(borrowerDtos.get(0).getBorrowerAddress());
                        caseDto.setBorrowerIdcard(key);
                        caseDto.setBorrowerTel(borrowerDtos.get(0).getBorrowerTel());
                        caseDto.setAssetInstBatchId(assetInstBatchId);
                        caseDto.setBorrowerName(borrowerDtos.get(0).getBorrowerName());
                        caseDto.setBorrowerNation(borrowerDtos.get(0).getBorrowerNation());
                        caseDto.setLawsuitPrincipalAmount(lawsuitPrincipalAmountSum);
                        caseDto.setLawsuitInterestAmount(lawsuitInterestAmountSum);
                        caseDto.setCreditPrincipalAmount(creditPrincipalAmountSum);
                        caseDto.setCreateUser(userId);
                        caseDto.setCreateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
                        caseDto.setCaseState(AgreementCaseSateMenu.GATHER.getLabel());
                        caseDto.setStated(1);
                        caseDtoList.add(caseDto);
                    }
                } else {
                    //检查当前人下的这几个合同的案件，然后查看案件的合同有哪些，若对应合同全部被删除或
                    Map<String, Set<String>> matchCaseAgreementMap = new HashMap<>();
                    for (Borrower borrower : borrowerDtos) {
                        Optional<String> checkCaseOptional = matchCaseAgreementList.stream().filter(caseAgreement -> borrower.getAgreementId().equals(caseAgreement.getAgreementId())).map(CaseAgreement::getCaseId).findFirst();
                        if (checkCaseOptional.isPresent()) {
                            String checkCase = checkCaseOptional.get();
                            if (!matchCaseAgreementMap.containsKey(checkCase)) {
                                Set<String> agreementIdList = matchCaseAgreementList.stream().filter(caseAgreement -> checkCase.equals(caseAgreement.getCaseId())).map(CaseAgreement::getAgreementId).collect(Collectors.toSet());
                                matchCaseAgreementMap.put(checkCase, agreementIdList);
                            }
                        }
                    }

                    if (CollectionUtil.isNotEmpty(matchCaseAgreementMap)) {
                        for (Map.Entry<String, Set<String>> entry : matchCaseAgreementMap.entrySet()) {
                            String caseId = entry.getKey();
                            Set<String> agreementIdList = entry.getValue();
                            BigDecimal lawsuitPrincipalAmountSum = BigDecimal.ZERO;
                            BigDecimal creditPrincipalAmountSum = BigDecimal.ZERO;
                            BigDecimal lawsuitInterestAmountSum = BigDecimal.ZERO;
                            int removeCount = agreementIdList.size();
                            for (String agreementId : agreementIdList) {
                                //存在当前导入数据中
                                Optional<Agreement> agreementOptional = agreementDtoList.stream().filter(agreement -> agreement.getId().equals(agreementId)).findFirst();
                                if (!agreementOptional.isPresent()) {
                                    //如果导入数据不存在则找目前已有的数据
                                    agreementOptional = agreements.stream().filter(agreement -> agreement.getId().equals(agreementId)).findFirst();
                                }
                                Agreement agreement = agreementOptional.get();
                                if (AgreementCaseSateMenu.ABOLISH_CASE.getLabel().equals(agreement.getCaseState())) {
                                    removeCount = removeCount - 1;
                                } else {
                                    if (agreement.getLawsuitPrincipalAmount() != null) {
                                        lawsuitPrincipalAmountSum = lawsuitPrincipalAmountSum.add(new BigDecimal(agreement.getLawsuitPrincipalAmount()));
                                    }
                                    if (agreement.getCreditPrincipalAmount() != null) {
                                        creditPrincipalAmountSum = creditPrincipalAmountSum.add(new BigDecimal(agreement.getCreditPrincipalAmount()));
                                    }
                                    if (agreement.getLawsuitInterestAmount() != null) {
                                        lawsuitInterestAmountSum = lawsuitInterestAmountSum.add(new BigDecimal(agreement.getLawsuitInterestAmount()));
                                    }
                                }
                            }
                            if (removeCount == 0) {
                                //删除案件
                                delCaseIdList.add(caseId);
                            } else {
                                BsCase caseDto = new BsCase();
                                caseDto.setId(caseId);
                                caseDto.setLawsuitPrincipalAmount(lawsuitPrincipalAmountSum);
                                caseDto.setLawsuitInterestAmount(lawsuitInterestAmountSum);
                                caseDto.setCreditPrincipalAmount(creditPrincipalAmountSum);
                                caseDto.setOperateUser(userId);
                                caseDto.setOperateTime(DateTimeUtil.currentDate());
                                caseDto.setBorrowerAddress(borrowerDtos.get(0).getBorrowerAddress());
                                caseDto.setBorrowerTel(borrowerDtos.get(0).getBorrowerTel());
                                caseDto.setBorrowerNation(borrowerDtos.get(0).getBorrowerNation());
                                caseDto.setStated(2);
                                caseDtoList.add(caseDto);
                            }
                        }
                    }
                }
            } else {
                //未存在的案件数据则直接产生合同和案件
                String caseId = idWorker.generateId();
                List<String> set = agreementDtoList.stream().filter(agreement -> agreement.getBorrowerIdcard().equals(key) && "0".equals(agreement.getComplateState())).map(Agreement::getId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(set)) {
                    BigDecimal lawsuitPrincipalAmountSum = borrowDetailDtoList.stream().filter(item -> set.contains(item.getAgreementId())).map(BorrowDetail::getLawsuitPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                    BigDecimal creditPrincipalAmountSum = borrowDetailDtoList.stream().filter(item -> set.contains(item.getAgreementId())).map(BorrowDetail::getCreditPrincipalAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                    BigDecimal lawsuitInterestAmountSum = borrowDetailDtoList.stream().filter(item -> set.contains(item.getAgreementId())).map(BorrowDetail::getLawsuitInterestAmount).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
                    BsCase caseDto = new BsCase();
                    caseDto.setId(caseId);
                    caseDto.setBorrowerAddress(borrowerDtos.get(0).getBorrowerAddress());
                    caseDto.setBorrowerIdcard(key);
                    caseDto.setBorrowerTel(borrowerDtos.get(0).getBorrowerTel());
                    caseDto.setAssetInstBatchId(assetInstBatchId);
                    caseDto.setBorrowerName(borrowerDtos.get(0).getBorrowerName());
                    caseDto.setBorrowerNation(borrowerDtos.get(0).getBorrowerNation());
                    caseDto.setLawsuitPrincipalAmount(lawsuitPrincipalAmountSum);
                    caseDto.setLawsuitInterestAmount(lawsuitInterestAmountSum);
                    caseDto.setCreditPrincipalAmount(creditPrincipalAmountSum);
                    caseDto.setCreateUser(userId);
                    caseDto.setCreateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
                    caseDto.setCaseState(AgreementCaseSateMenu.GATHER.getLabel());
                    caseDto.setStated(1);
                    caseDtoList.add(caseDto);

                    for (String agreementId : set) {
                        AgreementCase agreementCaseDto = new AgreementCase();
                        agreementCaseDto.setCaseId(caseId);
                        agreementCaseDto.setAgreementId(agreementId);
                        agreementCaseDtoList.add(agreementCaseDto);
                    }
                }
            }
        }

        List<Agreement> saveAgreementList = agreementDtoList.parallelStream().filter(agreement -> !agreement.getUpdated()).collect(Collectors.toList());
        List<Agreement> uptAgreementList = agreementDtoList.parallelStream().filter(Agreement::getUpdated).collect(Collectors.toList());

        if (CollectionUtil.isNotEmpty(saveAgreementList)) {
            agreementMapper.batchSaveAgreement(saveAgreementList);
            agreementMapper.batchSaveAgreementExpand(agreementExpandDtoList.parallelStream().filter(agreement -> !agreement.getUpdated()).collect(Collectors.toList()));
            bsBorrowDetailMapper.batchSaveBsBorrowDetail(borrowDetailDtoList.parallelStream().filter(agreement -> !agreement.getUpdated()).collect(Collectors.toList()));
            borrowerMapper.batchSaveBorrower(borrowerDtoList.parallelStream().filter(agreement -> !agreement.getUpdated()).collect(Collectors.toList()));
            List<AgreementStateRecord> agreementStateRecordList = saveAgreementList.stream().map(agreement -> {
                AgreementStateRecord agreementStateRecord = new AgreementStateRecord();
                agreementStateRecord.setId(idWorker.generateId());
                agreementStateRecord.setNewState(agreement.getCaseState());
                agreementStateRecord.setContractId(agreement.getId());
                agreementStateRecord.setCreateUser(userId);
                return agreementStateRecord;
            }).collect(Collectors.toList());
            agreementMapper.batchSaveAgreementRecord(agreementStateRecordList);
        }
        if (CollectionUtil.isNotEmpty(uptAgreementList)) {
            agreementMapper.batchOptAgreement(uptAgreementList);
            List<AgreementStateRecord> agreementStateRecordList = uptAgreementList.stream().map(agreement -> {
                Agreement oldAgreement = agreements.stream().filter(checkAgreement -> agreement.getId().equals(checkAgreement.getId())).findFirst().get();
                AgreementStateRecord agreementStateRecord = new AgreementStateRecord();
                if (!oldAgreement.getCaseState().equals(agreement.getCaseState()) || null != agreement.getCaseState()) {
                    agreementStateRecord.setOldState(oldAgreement.getCaseState());
                }
                agreementStateRecord.setId(idWorker.generateId());
                agreementStateRecord.setNewState(agreement.getCaseState());
                agreementStateRecord.setContractId(agreement.getId());
                agreementStateRecord.setCreateUser(userId);
                return agreementStateRecord;
            }).collect(Collectors.toList());
            agreementStateRecordList = agreementStateRecordList.stream().filter(agreementStateRecord -> null == agreementStateRecord.getOldState()).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(agreementStateRecordList)) {
                agreementMapper.batchSaveAgreementRecord(agreementStateRecordList);
            }

            agreementMapper.batchOptAgreementExpand(agreementExpandDtoList.parallelStream().filter(AgreementExpand::getUpdated).collect(Collectors.toList()));
            bsBorrowDetailMapper.batchOptBsBorrowDetail(borrowDetailDtoList.parallelStream().filter(BorrowDetail::getUpdated).collect(Collectors.toList()));
            borrowerMapper.batchUptBorrower(borrowerDtoList.parallelStream().filter(Borrower::getUpdated).collect(Collectors.toList()));
        }

        //合同案件关联
        if (CollectionUtil.isNotEmpty(agreementCaseDtoList)) {
            agreementMapper.batchSaveAgreementCase(agreementCaseDtoList);
        }
        //如果合同是废案则移除对应案件和关联关系
        if (CollectionUtil.isNotEmpty(delCaseAgreementIdList)) {
            agreementMapper.deleteAgreementCaseByAgreementIds(delCaseAgreementIdList);
        }
        if (CollectionUtil.isNotEmpty(caseDtoList)) {
            //案件添加
            List<BsCase> caseSaveList = caseDtoList.parallelStream().filter(agreement -> 1 == agreement.getStated()).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(caseSaveList)) {
                bsCaseMapper.batchSaveBsCase(caseSaveList);

                List<CaseStateRecord> caseStateRecordList = caseSaveList.stream().map(cases -> {
                    CaseStateRecord caseStateRecord = new CaseStateRecord();
                    caseStateRecord.setId(idWorker.generateId());
                    caseStateRecord.setNewState("gather");
                    caseStateRecord.setCaseId(cases.getId());
                    caseStateRecord.setCreateUser(userId);
                    return caseStateRecord;
                }).collect(Collectors.toList());
                bsCaseMapper.batchStateRecord(caseStateRecordList);
            }

            //案件修改
            List<BsCase> caseUptList = caseDtoList.parallelStream().filter(agreement -> 2 == agreement.getStated()).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(caseUptList)) {
                bsCaseMapper.batchOptBsCase(caseUptList);
            }
        }

        if (CollectionUtil.isNotEmpty(delCaseIdList)) {
            bsCaseMapper.batchMapperDel(delCaseIdList);
            bsCaseMapper.batchDelRecord(delCaseIdList);
            bsCaseMapper.batchDelCase(delCaseIdList);
        }

        sqlSession.flushStatements();
        sqlSession.commit();
        sqlSession.clearCache();
        sqlSession.close();
        return Result.ok();
    }


    /**
     * 合同赋值
     *
     * @param id
     * @param bsDataDetailExportTemplate
     * @param assetInstBatchId
     * @param updated
     * @param idCardUpdated
     * @param currentState
     * @param lastState
     * @return
     */
    private Agreement installAgreement(String id, BsDataDetailExportTemplate bsDataDetailExportTemplate, String assetInstBatchId, Boolean updated, Boolean idCardUpdated, String currentState, String lastState) {
        String userId = GlobalHeaderThreadLocal.getOrException().getUserId();
        Agreement agreementDto = new Agreement();
        agreementDto.setId(id);
        agreementDto.setUpdated(updated);
        agreementDto.setIdCardUpdated(idCardUpdated);
        agreementDto.setContractNo(bsDataDetailExportTemplate.getContract_no());
        agreementDto.setContractTime(bsDataDetailExportTemplate.getContract_time());
        agreementDto.setCreditor(bsDataDetailExportTemplate.getCreditor());
        agreementDto.setPlaintiff(bsDataDetailExportTemplate.getPlaintiff());
        agreementDto.setPlatformName(bsDataDetailExportTemplate.getPlatform_name());
        agreementDto.setLenders(bsDataDetailExportTemplate.getLenders());
        agreementDto.setBorrowPeriod(bsDataDetailExportTemplate.getBorrow_period());
        agreementDto.setBorrowStartTime(bsDataDetailExportTemplate.getBorrow_start_time());
        agreementDto.setBorrowEndTime(bsDataDetailExportTemplate.getBorrow_end_time());
        agreementDto.setLawsuitPrincipalAmount(bsDataDetailExportTemplate.getLawsuit_principal_amount());
        agreementDto.setLawsuitInterestAmount(bsDataDetailExportTemplate.getLawsuit_interest_amount());
        agreementDto.setCreditPrincipalAmount(bsDataDetailExportTemplate.getCredit_principal_amount());
        agreementDto.setAssetInstBatchId(assetInstBatchId);
        if (!updated) {
            agreementDto.setCaseState(AgreementCaseSateMenu.GATHER.getLabel());
            agreementDto.setComplateState("0");
        }
        if (new BigDecimal(bsDataDetailExportTemplate.getLawsuit_subject_amount()).compareTo(BigDecimal.ZERO) <= 0) {
            agreementDto.setCaseState(AgreementCaseSateMenu.ABOLISH_CASE.getLabel());
            agreementDto.setComplateState("1");
        } else if (updated) {
            //如果修改之前是废案
            if (AgreementCaseSateMenu.ABOLISH_CASE.getLabel().equals(currentState) && null != lastState) {
                AgreementCaseSateMenu stateMenu = AgreementCaseSateMenu.getByLabel(lastState);
                agreementDto.setCaseState(lastState);
                agreementDto.setComplateState(stateMenu.getState());
            }
        }
        agreementDto.setBorrowerIdcard(bsDataDetailExportTemplate.getBorrower_idcard());
        if (updated) {
            agreementDto.setOperateUser(userId);
            agreementDto.setOperateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
        } else {
            agreementDto.setCreateUser(userId);
            agreementDto.setCreateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
        }

        return agreementDto;
    }

    /**
     * 借款人信息
     *
     * @param agreementId
     * @param bsDataDetailExportTemplate
     * @return
     */
    private Borrower installBorrower(String agreementId, BsDataDetailExportTemplate bsDataDetailExportTemplate, Boolean updated, Boolean idCardUpdated) {
        Borrower borrowerDto = new Borrower();
        borrowerDto.setId(agreementId);
        borrowerDto.setUpdated(updated);
        borrowerDto.setIdCardUpdated(idCardUpdated);
        borrowerDto.setAgreementId(agreementId);
        borrowerDto.setBorrowerName(bsDataDetailExportTemplate.getBorrower_name());
        borrowerDto.setBorrowerIdcard(bsDataDetailExportTemplate.getBorrower_idcard());
        borrowerDto.setBorrowerAddress(bsDataDetailExportTemplate.getBorrower_address());
        borrowerDto.setBorrowerTel(bsDataDetailExportTemplate.getBorrower_tel());
        borrowerDto.setBorrowerNation(bsDataDetailExportTemplate.getBorrower_nation());
        borrowerDto.setRegisterId(bsDataDetailExportTemplate.getRegister_id());
        if (updated) {
            borrowerDto.setOperateUser(GlobalHeaderThreadLocal.get().getUserId());
            borrowerDto.setOperateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
        } else {
            borrowerDto.setCreateUser(GlobalHeaderThreadLocal.get().getUserId());
            borrowerDto.setCreateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
        }
        return borrowerDto;
    }

    /**
     * 借款人详情
     *
     * @param agreementId
     * @param bsDataDetailExportTemplate
     * @return
     */
    private BorrowDetail installBorrowDetail(String agreementId, BsDataDetailExportTemplate bsDataDetailExportTemplate, Boolean updated, Boolean idCardUpdated) {
        BorrowDetail borrowDetailDto = new BorrowDetail();
        borrowDetailDto.setId(agreementId);
        borrowDetailDto.setAgreementId(agreementId);
        borrowDetailDto.setUpdated(updated);
        borrowDetailDto.setIdCardUpdated(idCardUpdated);
        borrowDetailDto.setCreditPrincipalAmount(bsDataDetailExportTemplate.getCredit_principal_amount());
        borrowDetailDto.setLawsuitPrincipalAmount(bsDataDetailExportTemplate.getLawsuit_principal_amount());
        borrowDetailDto.setPaidPrincipalAmount(bsDataDetailExportTemplate.getPaid_principal_amount());
        borrowDetailDto.setContractualPrincipalAmount(bsDataDetailExportTemplate.getContractual_principal_amount());
        borrowDetailDto.setLawsuitInterestAmount(bsDataDetailExportTemplate.getLawsuit_interest_amount());
        borrowDetailDto.setDailyInterestRate(bsDataDetailExportTemplate.getDaily_interest_rate());
        borrowDetailDto.setRepayableInterestAmount(bsDataDetailExportTemplate.getRepayable_interest_amount());
        borrowDetailDto.setPaidInterestAmount(bsDataDetailExportTemplate.getPaid_interest_amount());
        borrowDetailDto.setOverdueInterestRate(bsDataDetailExportTemplate.getOverdue_interest_rate());
        borrowDetailDto.setOverdueStartTime(bsDataDetailExportTemplate.getOverdue_start_time());
        borrowDetailDto.setLitigationFines(bsDataDetailExportTemplate.getLitigation_fines());
        borrowDetailDto.setLawsuitSubjectAmount(bsDataDetailExportTemplate.getLawsuit_subject_amount());
        borrowDetailDto.setCompensatoryPrincipalAmount(bsDataDetailExportTemplate.getCompensatory_principal_amount());
        borrowDetailDto.setCompensatoryInterestAmount(bsDataDetailExportTemplate.getCompensatory_interest_amount());
        borrowDetailDto.setCompensatoryPenaltyAmount(bsDataDetailExportTemplate.getCompensatory_penalty_amount());
        borrowDetailDto.setCompensatoryBreachAmount(bsDataDetailExportTemplate.getCompensatory_breach_amount());
        if (updated) {
            borrowDetailDto.setOperateUser(GlobalHeaderThreadLocal.get().getUserId());
            borrowDetailDto.setOperateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
        } else {
            borrowDetailDto.setCreateUser(GlobalHeaderThreadLocal.get().getUserId());
            borrowDetailDto.setCreateTime(DateTimeUtil.fromDateTime(LocalDateTime.now()));
        }
        return borrowDetailDto;
    }

    private AgreementExpand installAgreementExpand(String agreementId, BsDataDetailExportTemplate bsDataDetailExportTemplate, Boolean updated, Boolean idCardUpdated) {
        AgreementExpand agreementExpandDto = new AgreementExpand();
        agreementExpandDto.setUpdated(updated);
        agreementExpandDto.setIdCardUpdated(idCardUpdated);
        agreementExpandDto.setAgreementId(agreementId);
        agreementExpandDto.setExpandAmount1(bsDataDetailExportTemplate.getExpand_amount1());
        agreementExpandDto.setExpandAmount2(bsDataDetailExportTemplate.getExpand_amount2());
        agreementExpandDto.setExpandAmount3(bsDataDetailExportTemplate.getExpand_amount3());
        agreementExpandDto.setExpandAmount4(bsDataDetailExportTemplate.getExpand_amount4());
        agreementExpandDto.setExpandAmount5(bsDataDetailExportTemplate.getExpand_amount5());

        agreementExpandDto.setExpandDate1(bsDataDetailExportTemplate.getExpand_date1());
        agreementExpandDto.setExpandDate2(bsDataDetailExportTemplate.getExpand_date2());
        agreementExpandDto.setExpandDate3(bsDataDetailExportTemplate.getExpand_date3());
        agreementExpandDto.setExpandDate4(bsDataDetailExportTemplate.getExpand_date4());
        agreementExpandDto.setExpandDate5(bsDataDetailExportTemplate.getExpand_date5());

        agreementExpandDto.setExpandNum1(bsDataDetailExportTemplate.getExpand_num1());
        agreementExpandDto.setExpandNum2(bsDataDetailExportTemplate.getExpand_num2());
        agreementExpandDto.setExpandNum3(bsDataDetailExportTemplate.getExpand_num3());
        agreementExpandDto.setExpandNum4(bsDataDetailExportTemplate.getExpand_num4());
        agreementExpandDto.setExpandNum5(bsDataDetailExportTemplate.getExpand_num5());

        agreementExpandDto.setExpandText1(bsDataDetailExportTemplate.getExpand_text1());
        agreementExpandDto.setExpandText2(bsDataDetailExportTemplate.getExpand_text2());
        agreementExpandDto.setExpandText3(bsDataDetailExportTemplate.getExpand_text3());
        agreementExpandDto.setExpandText4(bsDataDetailExportTemplate.getExpand_text4());
        agreementExpandDto.setExpandText5(bsDataDetailExportTemplate.getExpand_text5());

        agreementExpandDto.setExpense1(bsDataDetailExportTemplate.getExpense_1());
        agreementExpandDto.setExpense2(bsDataDetailExportTemplate.getExpense_2());
        agreementExpandDto.setExpense3(bsDataDetailExportTemplate.getExpense_3());
        agreementExpandDto.setExpense4(bsDataDetailExportTemplate.getExpense_4());
        agreementExpandDto.setExpense5(bsDataDetailExportTemplate.getExpense_5());

        agreementExpandDto.setBorrowerIdentifier1(bsDataDetailExportTemplate.getBorrower_identifier_1());
        agreementExpandDto.setBorrowerIdentifier2(bsDataDetailExportTemplate.getBorrower_identifier_2());
        agreementExpandDto.setBorrowerIdentifier3(bsDataDetailExportTemplate.getBorrower_identifier_3());
        agreementExpandDto.setBorrowerIdentifier4(bsDataDetailExportTemplate.getBorrower_identifier_4());
        agreementExpandDto.setBorrowerIdentifier5(bsDataDetailExportTemplate.getBorrower_identifier_5());

        agreementExpandDto.setContractIdentifier1(bsDataDetailExportTemplate.getContract_identifier_1());
        agreementExpandDto.setContractIdentifier2(bsDataDetailExportTemplate.getContract_identifier_2());
        agreementExpandDto.setContractIdentifier3(bsDataDetailExportTemplate.getContract_identifier_3());
        agreementExpandDto.setContractIdentifier4(bsDataDetailExportTemplate.getContract_identifier_4());
        agreementExpandDto.setContractIdentifier5(bsDataDetailExportTemplate.getContract_identifier_5());
        return agreementExpandDto;
    }


}


